package vboot.core.framework.security.authc;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import vboot.core.common.mvc.api.R;
import vboot.core.framework.config.AppConfig;
import vboot.core.framework.cache.RedisHandler;
import vboot.core.framework.security.authz.JwtHandler;
import vboot.core.framework.security.pojo.*;
import vboot.core.module.mon.log.login.MonLogLoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.websocket.server.PathParam;
import java.util.HashMap;
import java.util.Map;

//认证API:主要包含登录登出、token刷新、菜单获取、用户信息获取
@RestController
public class AuthcApi {

    //登录
    @PostMapping("/login")
    public R login(@Valid @RequestBody LoginVo loginVo, HttpServletRequest request) {
        //1.登录验证
        UserDo userDo =  authcService.getDbUserByUsername(loginVo.getUsername());;
        boolean passFlag = authcService.check(userDo, loginVo);
        if (!passFlag) {
            return R.build(402, "账号不存在或密码错误");
        }

        //2.创建accessToken与refreshToken
        String atokenUUID = IdUtil.simpleUUID();
        String atoken = jwtHandler.createTokenByUuid(atokenUUID);
        String rtoken = jwtHandler.createTokenByUuid(loginVo.getUsername());//需要加密下

        Map<String, Object> backMap = new HashMap<>();
        backMap.put("token", atoken);
        backMap.put("rtoken", rtoken);

        //3.初始化用户信息，获取门户，菜单与按钮
//        Zuser zuser = new Zuser(userDo.getId(), userDo.getName(), loginVo.getUsername(),userDo.getCorid(),userDo.getType());
        Zuser zuser = new Zuser(userDo);
        authcService.initZuser(zuser, userDo, backMap); //这个方法非常重要

        redisHandler.set("online-key:" + atokenUUID, zuser, appConfig.getJwt().getAtime());//默认8小时过期

        //4.异步方式记录登录日志
        monLogLoginService.save("online-key:" + atokenUUID, zuser, request);
        return R.ok(backMap);
    }

    //token刷新
    @GetMapping("/rtoken")
    public R rtoken(@PathParam("token2") String token2) {
        System.out.println("token2=" + token2);
        String username = jwtHandler.getClaims(token2).getId();
        System.out.println("username=" + username);
        String uuid = IdUtil.simpleUUID();
        String token = jwtHandler.createTokenByUuid(uuid);
        Zuser zuser = authcService.getUser(username);
        redisHandler.set(uuid, zuser, 10000 / 1000);
        Map<String, Object> backMap = new HashMap<>();
        backMap.put("token", token);
        return R.ok(backMap);
    }

    //登出
    @GetMapping("/logout")
    public R logout(Authentication auth) {
        return R.ok();
    }

    //获取用户信息
    @GetMapping("/getUserInfo")
    public R getUserInfo(Authentication auth, HttpServletRequest request) {
        Zuser zuser = (Zuser) auth.getPrincipal();
        return R.ok(zuser);
    }

    //获取菜单树
    @GetMapping("/getMenuList")
    public R getMenuList(String porid, Authentication auth, HttpServletRequest request) {
        if (auth == null) {
            return R.build(401, "登录过期");
        }
        Map<String, Object> backMap = new HashMap<>();
        Zuser zuser = (Zuser) auth.getPrincipal();

        if (StrUtil.isBlank(porid)) {
            UserDo userDo= authcService.getDbUserById(zuser.getId());
            authcService.initZuser(zuser, userDo, backMap);
        } else {
            authcService.switchPortal(zuser, backMap, porid);
        }
        return R.ok(backMap);
    }

    @Autowired
    private AuthcService authcService;

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private RedisHandler redisHandler;

    @Autowired
    private JwtHandler jwtHandler;

    @Autowired
    private MonLogLoginService monLogLoginService;


}
